package com.Lgwd.service.chat.impl;

import cn.hutool.core.util.URLUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.Lgwd.config.GptProperties;
import com.Lgwd.entity.ChatKey;
import com.Lgwd.entity.Dialogue;
import com.Lgwd.entity.vo.AiGcFunGptVo;
import com.Lgwd.entity.vo.AiGcFunResultVo;
import com.Lgwd.service.chat.IChatGptService;
import com.Lgwd.utils.ResponseData;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author sunchuanchuan
 * @version V1.0
 * @date 2023/3/22
 * @package com.Lgwd.service.chat.impl
 * @description  https://chat.forchange.cn/
 **/
@Service
@Slf4j
public class AiGcFunGptServiceImpl extends IChatGptService {

    public static final String KEY_URL = "https://api.aigcfun.com/fc/key";
    public static final String DIALOGUE_URL = "https://api.aigcfun.com/api/v1/text";

    @Autowired
    private GptProperties gptProperties;

    @Override
    public String getGptKey() {
        HttpRequest httpRequest = HttpRequest.get(KEY_URL);
        httpRequest.timeout(gptProperties.getTimeOut());
        HttpResponse execute = httpRequest.execute();
        ResponseData<String> responseData = JSON.parseObject(execute.body(), ResponseData.class);
        log.info("获取key返回的http--->" + execute);
        log.info("获取key返回的body--->" + execute.body());
        if (responseData.getErrCode() == 0) {
            return responseData.getData();
        }
        return null;
    }

    @Override
    public ResponseData<?> getKeyToDataBase() {
        try {
            String key = getGptKey();
            if (ObjectUtils.isEmpty(key)) {
                return ResponseData.defaultSuccess();
            }
            ChatKey chatKey = new ChatKey();
            chatKey.setApi_key(key).setType(0).setStatus(0).setUseDate(0);
            ChatKey saveChatKey = saveChatKey(chatKey);
            return ResponseData.ok(saveChatKey);
        } catch (Exception e) {
           e.printStackTrace();
        }
        return ResponseData.defaultFail();
    }

    private static int requestsNum = 0;

    private static String gptKey = "";


    private List<AiGcFunGptVo.Message> getMessages(Dialogue dialogue){
        long dialogueId = dialogue.getDialogue_id();
        List<Dialogue> dialogues = selectDialogueListByDialogueId(dialogueId);
        List<AiGcFunGptVo.Message> result = new LinkedList<>();
        dialogues.stream().filter(temp-> "user".equals(temp.getRole())).forEach(temp->{
            AiGcFunGptVo.Message message = new AiGcFunGptVo.Message();
            message.setContent(temp.getMessages());
            message.setRole(temp.getRole());
            result.add(message);
            Dialogue data = dialogues.stream().filter(dia -> "assistant".equals(dia.getRole()) && dia.getPid().equals(temp.getId())).findFirst().orElse(null);
            if (data != null) {
                AiGcFunGptVo.Message assistant = new AiGcFunGptVo.Message();
                assistant.setContent(data.getMessages());
                assistant.setRole(data.getRole());
                result.add(assistant);
            }
        });
        result.add(new AiGcFunGptVo.Message("user", dialogue.getMessages()));
        return result;
    }



    @Override
    public String dialogue(Dialogue message) {
        log.info("页面传来的数据---->" + JSON.toJSONString(message));
        AiGcFunGptVo aiGcFunGptVo = new AiGcFunGptVo();
        List<AiGcFunGptVo.Message> messages = getMessages(message);
        aiGcFunGptVo.setMessages(messages);
        if (ObjectUtils.isEmpty(gptKey) || requestsNum > 10) {
            ChatKey chatKey = findKey(0);
            gptKey =chatKey.getApi_key();
            requestsNum = 0;
            if (gptKey == null) {
                return "没有可以使用的key了。";
            }
        }

        int sum = messages.stream().filter(user-> "user".equals(user.getRole())).mapToInt(temp -> temp.getContent().length()).sum();
        aiGcFunGptVo.setTokensLength(aiGcFunGptVo.getTokensLength() + sum);
        Map<String, Object> map = new HashMap<>();
        map.put("key", gptKey);
        String query = URLUtil.buildQuery(map, StandardCharsets.UTF_8);
        String url = DIALOGUE_URL + "?" + query;
        if (ObjectUtils.isEmpty(gptKey)) {
            return null;
        }
        HttpRequest post = HttpRequest.post(url);
        post.timeout(gptProperties.getTimeOut());
        post.body(JSON.toJSONString(aiGcFunGptVo));
        post.contentType(ContentType.JSON.getValue());
        log.info("开始请求接口");
        HttpResponse execute = post.execute();
        String body = execute.body();
        log.info("请求接口返回的数据--->" + body);
        AiGcFunResultVo aiGcFunResult = JSON.parseObject(body, AiGcFunResultVo.class);
        if (aiGcFunResult.getErrCode() == 0) {
            requestsNum++;
            message.setRole("user");
            message.setCreateTime(System.currentTimeMillis());


            Dialogue systemDialogue = new Dialogue();
            systemDialogue.setDialogue_id(message.getDialogue_id());
            systemDialogue.setCreateTime(System.currentTimeMillis());
            systemDialogue.setUser_account(message.getUser_account());
            //保存系統消息
            systemDialogue.setRole("assistant");
            String text = aiGcFunResult.getChoices().get(0).getText();
            if (ObjectUtils.isEmpty(text)) {
                return null;
            }
            Dialogue dialogue = saveDialogue(message);
            systemDialogue.setPid(dialogue.getId());
            systemDialogue.setMessages(text);
            saveDialogue(systemDialogue);
            return text;
        } else if (aiGcFunResult.getErrCode() == 8610002) {
            log.info("请求的key失效重新请求。");
            gptKey = "";
            requestsNum = 0;
            dialogue(message);
        }
        return null;
    }

}
